package cn.doourbest.learnspring.classloader;

import java.io.*;

public class MyClassLoader extends ClassLoader {

    private String rootDir;

    public MyClassLoader(String rootDir) {
        this.rootDir = rootDir;
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        if (rootDir == null) {
            return ClassLoader.getSystemClassLoader().loadClass(name);
        }
        byte[] classData = getClassData(name);
        if (classData == null) {
            throw new ClassNotFoundException();
        } else {
            return defineClass(name, classData, 0, classData.length);
        }
    }

    private byte[] getClassData(String className) throws ClassNotFoundException {
        String path = classNameToPath(className);
        try {
            InputStream ins = new FileInputStream(path);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            int bytesNumRead = 0;
            while ((bytesNumRead = ins.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesNumRead);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private String classNameToPath(String className) {
        return rootDir + File.separatorChar
                + className.replace('.', File.separatorChar) + ".class";
    }

    public static void main(String[] args) {
        try {
            MyClassLoader myClassLoader = new MyClassLoader("E:\\eclipseworkspace\\ZSCLeanrSpring\\target\\classes\\");
            String clazzName = "cn.doourbest.learnspring.classloader.MyService";
            Class<?> myService = myClassLoader.findClass(clazzName);

            Object o1 = myService.newInstance();
            MyService o = new MyService();
            //System.out.println(myService.getDeclaredMethod("getName1").invoke(o1));
            System.out.println(myService.getDeclaredMethod("getName").invoke(o1));

            MyClassLoader mm = new MyClassLoader(null);
            Class<?> aClass = mm.findClass("java.lang.String");

            System.out.println(myService.getDeclaredMethod("getAge", aClass).invoke(o, "ff"));
            //System.out.println(o.getClass().getDeclaredMethod("getName", MyService.class).invoke(myService.newInstance()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
